home *** CD-ROM | disk | FTP | other *** search
/ The Best of Down Under Games / The Best of Down Under Games.iso / 3dfx Screen Savers / 3dEnvironment / SOURCE.ZIP / test.cpp < prev    next >
C/C++ Source or Header  |  1997-07-25  |  11KB  |  404 lines

  1. /****************************************************************************
  2.  
  3. Probable Worlds
  4.  
  5. Copyright 1997 (c) Complex
  6.  
  7. Design and Programming by Jarno Heikkinen (jarnoh@yomimedia.fi)
  8.  
  9. ****************************************************************************/
  10.  
  11. #include "stdafx.h"
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <windows.h>
  15.  
  16. #include "saver.h"
  17. #include "test.h"
  18.  
  19. #pragma warning( once : 4305 4244 )
  20. #include "klunssi.h"
  21.  
  22. extern TCHAR szConfig[]; //=_T("Config");
  23.  
  24. // quick macro to scale 32bit ABGR color (uses fadetab scaling table)
  25. #define FADE(q) (fadetab[q&0xff]|(fadetab[(q&0xff00)>>8]<<8)|(fadetab[(q&0xff0000)>>16]<<16))
  26.  
  27. // different fog colors
  28. FxU32 fogColors[]={ 
  29.     0xc0c0c0c0, 
  30.     0x00000000, 
  31.     0x00302000, 
  32.     0x00307070, 
  33.     0x00804020, 
  34.     0x001050e0, 
  35.     0x00405050, 
  36.     0x00c01060, 
  37.     0x0000d0d0,
  38.     0x00ff0040,
  39.     0x000040ff 
  40. };
  41.  
  42.  
  43. /****************************************************************************/
  44.  
  45. Probe::Probe() 
  46. {
  47.     GrHwConfiguration hwconfig;
  48.  
  49. #ifndef NOMUSIC
  50.     MIDASstartup();
  51. #endif
  52.  
  53.     // Initialize Glide 
  54.     grGlideInit();
  55.     grSstQueryHardware( &hwconfig );
  56.     grSstSelect( 0 );
  57.  
  58.     frames=-1;
  59.     kala=0;
  60.     initok=0;
  61. }
  62.  
  63. /****************************************************************************/
  64. void Probe::prepare()
  65. {
  66.     int i;
  67.     float asdf=0.;
  68.  
  69.     // load texture data from resources
  70.     // 666 is our resource ID
  71.     HRSRC hRes;
  72.     hRes = FindResource(NULL, "#666", "texture");
  73.  
  74.     if(hRes)
  75.     {
  76.         bmpsize=SizeofResource(NULL, hRes);
  77.         bmp=new FxU8[bmpsize];
  78.         memcpy(bmp, LockResource(LoadResource(NULL, hRes)), bmpsize);
  79.     }
  80.     else 
  81.     {
  82.         bmp=NULL;
  83.         bmpsize=0;
  84. //        MessageBox(NULL, "perkele", "", MB_OK);
  85.     }
  86.  
  87. //    FreeResource(hRes); 
  88.  
  89.     srand( GetTickCount() );
  90.  
  91.     // scale the object and calculate normals...
  92.     objvertAm=sizeof(objvert)/sizeof(objvert[0])/3;
  93.     objfaceAm=sizeof(objface)/sizeof(objface[0])/3;
  94.  
  95.     rotvert=new GrVertex[objvertAm];
  96.     objvn=new Vector3[objvertAm];
  97.  
  98.     memset(rotvert, 0, sizeof(GrVertex)*objvertAm);
  99.     memset(objvn, 0, sizeof(Vector3)*objvertAm);
  100.  
  101.     for(i=0;i<objvertAm*3;i++) if(objvert[i] > asdf) asdf=objvert[i];
  102.     for(i=0;i<objvertAm*3;i++) objvert[i]=objvert[i]*(1.f/asdf);
  103.  
  104.     objfn=new Vector3[objfaceAm];
  105.     for(i=0; i<objfaceAm; i++)
  106.     {
  107.         Vector3 tn;
  108.         Vector3 a=Vector3(&objvert[3*objface[i*3]]);
  109.         Vector3 b=Vector3(&objvert[3*objface[i*3+1]]);
  110.         Vector3 c=Vector3(&objvert[3*objface[i*3+2]]);
  111.         tn.x=  (b.y-a.y)*(c.z-a.z)-(c.y-a.y)*(b.z-a.z);
  112.         tn.y=-((b.x-a.x)*(c.z-a.z)-(c.x-a.x)*(b.z-a.z));
  113.         tn.z=  (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
  114.         objfn[i]=tn.normalize();
  115.     }
  116.  
  117.     for(i=0; i<objfaceAm*3; i++) objvn[objface[i]] += objfn[i/3];
  118.     for(i=0; i<objvertAm; i++) objvn[i]=objvn[i].normalize();
  119.  
  120.     // then some glide preparations... 
  121.     if(!grSstWinOpen( (unsigned long)AfxGetMainWnd()->m_hWnd, GR_RESOLUTION_640x480, GR_REFRESH_60Hz,
  122.         GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1 ))
  123.     {
  124.         MessageBox(NULL, "failed", "", MB_OK);
  125.         return;
  126.     };
  127.  
  128.     float sw=(float)grSstScreenWidth();
  129.     float sh=(float)grSstScreenHeight();
  130.  
  131.     texVerts[0].x = 0.f; texVerts[0].y = sh;
  132.     texVerts[1].x = sw; texVerts[1].y = sh;
  133.     texVerts[2].x = sw; texVerts[2].y = 0.f; 
  134.     texVerts[3].x = 0.f; texVerts[3].y = 0.f;
  135.     texVerts[0].oow=texVerts[1].oow=0.29f;
  136.     texVerts[2].oow=texVerts[3].oow=0.29f/24;
  137.  
  138.     // allocate space for texture (3dfx)
  139.     envMap = guTexAllocateMemory( 0, GR_MIPMAPLEVELMASK_BOTH, 256, 256,
  140.         GR_TEXFMT_P_8, GR_MIPMAP_NEAREST, GR_LOD_256, GR_LOD_256,
  141.         GR_ASPECT_1x1, GR_TEXTURECLAMP_CLAMP, GR_TEXTURECLAMP_CLAMP,
  142.         GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR, 0.0F, FXFALSE );
  143.  
  144.     texMap = guTexAllocateMemory( 0, GR_MIPMAPLEVELMASK_BOTH, 128, 128,
  145.         GR_TEXFMT_P_8, GR_MIPMAP_NEAREST, GR_LOD_128, GR_LOD_128,
  146.         GR_ASPECT_1x1, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP,
  147.         GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR, 0.0F, FXFALSE );
  148.  
  149.     // first texture is the envmap...
  150.     for(i=0;i<256;i++) envPal.data[i]=(bmp[i*3+32]<<16)+(bmp[i*3+1+32]<<8)+(bmp[i*3+2+32])&0xffffff;
  151.     guTexDownloadMipMap( envMap, bmp+800, NULL );
  152.  
  153.     memset(&texPal, 0, sizeof(texPal));
  154.  
  155.     for( i = 0; i < objvertAm; i++ ) rotvert[i].oow=1.f;
  156.  
  157.      grDepthMask(1);
  158.     grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
  159.     grDepthBufferFunction(GR_CMP_LESS);
  160.  
  161.     grDitherMode(GR_DITHER_DISABLE);
  162.      grCullMode(GR_CULL_POSITIVE);
  163.  
  164.     // default to solid screen write (full alpha -> no blur!)
  165.     grConstantColorValue(~0);
  166.  
  167.     grAlphaCombine( 
  168.         GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
  169.         GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_NONE,FXFALSE );
  170.     grColorCombine(
  171.         GR_COMBINE_FUNCTION_SCALE_OTHER,
  172.         GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE,
  173.         GR_COMBINE_OTHER_TEXTURE, FXFALSE);
  174.     grTexCombine(GR_TMU0,
  175.          GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,
  176.          GR_COMBINE_FUNCTION_LOCAL,GR_COMBINE_FACTOR_NONE,FXFALSE, FXFALSE);
  177.  
  178.     // generate fog table 
  179.     guFogGenerateExp( fogtable, .05f );
  180.     grFogTable( fogtable );
  181.     grFogMode( GR_FOG_WITH_TABLE );
  182.  
  183.     // save default rendering state
  184.     grGlideGetState(&defState);
  185.  
  186. // ========================================================================================
  187.     // setup background rendering state
  188.     grGlideSetState(&defState);
  189.     grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA,
  190.         GR_BLEND_ZERO, GR_BLEND_ZERO );
  191.     guTexSource(texMap);
  192.  
  193.     // always write pixels + depth 
  194.     // (background is full always so it does the clearing too :)
  195.     grDepthBufferFunction(GR_CMP_ALWAYS);
  196.     grGlideGetState(&bgState);    // save to bgState
  197. // ========================================================================================
  198.     // setup klunssi object rendering state
  199.     grGlideSetState(&defState);
  200.     grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
  201.     guTexSource(envMap);
  202.     grFogMode( GR_FOG_DISABLE );
  203.     grGlideGetState(&klunssiState); 
  204. // ========================================================================================
  205.  
  206. #ifndef NOMUSIC
  207.  
  208.     /* Initialize MIDAS and start background playback: */
  209.     module=NULL;
  210.     if( (AfxGetApp()->GetProfileInt(szConfig, _T("Mute"), 0)==0) && MIDASinit())
  211.     {
  212.         if(MIDASstartBackgroundPlay(100))
  213.         {
  214.             /* Load the module and start playing: */
  215. //            module = MIDASloadModule("d:\\projects\\glidetest\\trans.xm");
  216.             LPCTSTR name = AfxGetApp()->GetProfileString(szConfig, _T("FileName"), "");
  217.             module = MIDASloadModule((char*)name);
  218.             if(module) MIDASplayModule(module, 0);
  219.         }
  220.     }
  221. #endif
  222.  
  223.     // run at idle priority...
  224.     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
  225.     initok=1;
  226. }
  227.  
  228. /****************************************************************************/
  229. // randomize rotation and fog color
  230. void Probe::randomScene()
  231. {
  232.     if(!initok) this->prepare();
  233.  
  234.     float rd=1.f/(float)RAND_MAX; 
  235.     cameraRotate=(rand()*rd-.5f)*.015f;
  236.     cameraSpeed=(rand()*rd-.5f)*2.24f;
  237.     rotSpeed=Vector3(rand()*rd-.5f, rand()*rd-.5f, rand()*rd-.5f)*4.f;
  238.  
  239.     fogColor = fogColors[ rand() % (sizeof(fogColors)/sizeof(fogColors[0])) ];
  240.  
  241.     // get new texture .. there's 15 128x128 textures and 256x256 texture for envmap
  242.     FxU8 *pic=bmp+(rand()%15)*17184+66336;
  243.  
  244.     // download texture
  245.     guTexDownloadMipMap( texMap, pic+800, NULL );
  246.     // copy palette
  247.     for(int i=0;i<256;i++) texPal.data[i]=(pic[32+i*3]<<16)+(pic[32+i*3+1]<<8)+(pic[32+i*3+2])&0xffffff;
  248.  
  249.     // generate fog table 
  250.     guFogGenerateExp( fogtable, .0035f + ((rand()%100)*.001f) );
  251.     grFogTable( fogtable );
  252.  
  253.     // random blur amount
  254.     blurAm = rand()%192+64;
  255. }
  256.  
  257. /****************************************************************************/
  258. void Probe::run() 
  259. {
  260.     int i, j;
  261.     if(!initok) 
  262.     {
  263.         this->prepare();
  264.         return;
  265.     }
  266.  
  267.     if(frames<0)
  268.     {
  269.         timeold=GetTickCount();
  270.         kala=0;
  271.         frames=0;    
  272.         randomScene();
  273.     }
  274.  
  275.     float t=(GetTickCount()-timeold)*0.04f;
  276.  
  277.     j=frames;
  278.     if(j<0) j=0;
  279.     if(j>256) j=256;
  280.         
  281.     for(i=0;i<256;i++) fadetab[i]=(i*j)>>8;
  282.  
  283.     if(kala==0) frames+=1;
  284.     if(kala==1) frames-=3;
  285.  
  286.     if(frames>700) kala=1;
  287.  
  288.     Vector3 v=rotSpeed * (t*60.f*.00015f);
  289.  
  290.     // rotation matrix
  291.     Vector3 m0, m1, m2;
  292.     m0.x = (float)(cos(v.y) * cos(v.z) - sin(v.y) * sin(v.x) * sin(v.z));
  293.     m0.y = (float)(-cos(v.x) * sin(v.z));
  294.     m0.z = (float)(sin(v.y) * cos(v.z) + cos(v.y) * sin(v.x) * sin(v.z));
  295.     m1.x = (float)(cos(v.y) * sin(v.z) + sin(v.y) * sin(v.x) * cos(v.z));
  296.     m1.y = (float)(cos(v.x) * cos(v.z));
  297.     m1.z = (float)(sin(v.y) * sin(v.z) - cos(v.y) * sin(v.x) * cos(v.z));
  298.     m2.x = (float)(-sin(v.y) * cos(v.x));
  299.     m2.y = (float)(sin(v.x));
  300.     m2.z = (float)(cos(v.y) * cos(v.x));
  301.  
  302.     // screen center + magic snapping constant
  303.     // remove the snap and glide hangs nicely :)
  304.     float sw=(float)grSstScreenWidth();
  305.     float sh=(float)grSstScreenHeight();
  306.     float hw=sw*.5f+((float)( 3 << 18 ));
  307.     float hh=sh*.5f+((float)( 3 << 18 ));
  308.  
  309.     sh *= 1.2f; // aspect ratio fix
  310.  
  311.     for( i = 0; i < objvertAm; i++ ) 
  312.     {
  313.         // add pivot
  314.         Vector3 q=Vector3(objvert[i*3]+.8f, objvert[i*3+1], objvert[i*3+2]);
  315.  
  316.         v.x=m0.x*q.x+m0.y*q.y+m0.z*q.z;
  317.         v.y=m1.x*q.x+m1.y*q.y+m1.z*q.z;
  318.         v.z=m2.x*q.x+m2.y*q.y+m2.z*q.z+2.5f;  // + zdistance
  319.  
  320.         if(v.z<1.f) v.z=1.f;
  321.  
  322.         float ow=1.f/v.z;
  323.  
  324.         rotvert[i].oow=ow;
  325.  
  326.         v.x=v.x*sw*ow;
  327.         v.y=v.y*sh*ow;
  328.  
  329.         rotvert[i].x = v.x+hw;    
  330.         rotvert[i].y = v.y+hh;
  331.  
  332.         // rotate vertex normals
  333.         v.x=m0.x*objvn[i].x+m0.y*objvn[i].y+m0.z*objvn[i].z;
  334.         v.y=m1.x*objvn[i].x+m1.y*objvn[i].y+m1.z*objvn[i].z;
  335.         
  336.         // use them for envmap
  337.         rotvert[i].tmuvtx[0].sow = (1-v.x)*128.f*rotvert[i].oow;
  338.         rotvert[i].tmuvtx[0].tow = (1-v.y)*128.f*rotvert[i].oow;
  339.     }
  340.  
  341.     float ang=(float)t*cameraRotate;
  342.     float pos=t*cameraSpeed;
  343.     for(i=0;i<4;i++)
  344.     {
  345.         // this looks good enough :)
  346.         texVerts[i].tmuvtx[0].sow = (float)sin(ang)*13.f;
  347.         texVerts[i].tmuvtx[0].tow = (float)cos(ang)*13.f+pos*texVerts[i].oow; 
  348.         ang+=2*3.1415/4;
  349.     }
  350.  
  351.     grGlideSetState(&bgState);
  352.     grFogColorValue( FADE(fogColor) );
  353.     for(i=0;i<256;i++) realPal.data[i]=FADE(texPal.data[i]);
  354.     grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE, &realPal);
  355.  
  356.     // "motion blur" (for very dark fade phase we use solid (default))
  357.     if(frames>2) grConstantColorValue( blurAm<<24 );
  358.  
  359.     // draw the background
  360.     grDrawTriangle(&texVerts[0], &texVerts[1], &texVerts[2]);
  361.     grDrawTriangle(&texVerts[2], &texVerts[3], &texVerts[0]); 
  362.  
  363.     grGlideSetState(&klunssiState);
  364.  
  365.     for(i=0;i<256;i++) realPal.data[i]=FADE(envPal.data[i]);
  366.     grTexDownloadTable(GR_TMU0, GR_TEXTABLE_PALETTE, &realPal);
  367.  
  368.     // no clipping because we dont really draw that much polygons 
  369.     // and we fit into 3dfx "secure" area (+-1024 i think? :)
  370.     for( i = 0; i < objfaceAm; i++ ) 
  371.     {
  372.         grDrawTriangle(
  373.             rotvert+objface[i*3+0], 
  374.             rotvert+objface[i*3+1], 
  375.             rotvert+objface[i*3+2]);
  376.     }
  377.     framesTotal++;
  378.  
  379.     grSstIdle();
  380.     grBufferSwap(1);
  381. }
  382.  
  383. /****************************************************************************/
  384.  
  385. Probe::~Probe()
  386. {
  387.     grGlideShutdown();
  388.  
  389. #ifndef NOMUSIC
  390.     // Stop playing and deallocate module: 
  391.     if(module) MIDASstopModule(module);
  392.     if(module) MIDASfreeModule(module);
  393.  
  394.     module=NULL;
  395.  
  396.     // Stop background playback and uninitialize MIDAS: 
  397.     MIDASstopBackgroundPlay();
  398.     MIDASclose();
  399. #endif    
  400.  
  401.     return;
  402. }
  403.  
  404.